=begin pod :kind("Language") :subkind("Language") :category("fundamental")

=TITLE System interaction

=SUBTITLE Working with the underlying operating system and running applications

=head1 Getting arguments through the command line

The simplest way is to use the
L<C<@*ARGS>|/language/variables#%40%2AARGS> variable to obtain
arguments from the command line; this array will contain the strings that follow
the program name. L<C<%*ENV>|/language/variables#Runtime_environment> will
contain the environment variables, so that if you use:

=begin code :lang<shell>
export API_KEY=1967196417966160761fabc1511067
./consume_api.p6
=end code

You can use them from your program this way:

    my $api-key = %*ENV<API_KEY> // die "Need the API key";

This will fail if the environment variable C<API_KEY> has not been defined
previously.

Raku has a better way to deal with command line arguments if they represent
file names: the L<C<$*ARGFILES>|/language/variables#%24%2AARGFILES>
dynamic variable.

=begin code
for $*ARGFILES.lines -> $l {
    say "Long lines in {$*ARGFILES.path}"
        if $l.chars > 72 ;
}
=end code

You can run this program this way C<argfiles.p6 *.p6>, for instance, and it will
print a file name every time it finds a line longer than 72 characters.
C<$*ARGFILES> contains filehandles of all files described in the command lines-
C<.lines> will read in turn one line from every one of them, changing the value
of C<$*ARGFILES.path> every time a new handle is being processed. In general, it
provides a very convenient API for scripts that deal with sets of files.

=head1 Getting arguments interactively

Use C<prompt> to have a running program query the user for data:

=begin code
my UInt $num-iters = prompt "How many iterations to run: ";
=end code

=head1 Running programs synchronously and asynchronously

There are two routines to run external programs: L<C<run>|/routine/run> and
L<C<shell>|/routine/shell>. Both exist in the L<C<IO>|/type/IO> role and are
thus included in all classes that mix that role in, like L<IO::Path|/type/IO::Path>. Both
return a L<Proc|/type/Proc> object, but the main difference is that C<run> will
try to avoid the system shell, if possible, while C<shell> will run the command
through the default system shell.

The key class for running all external programs is L<Proc::Async|/type/Proc::Async>, which runs
processes asynchronously and allows
L<concurrent|/language/concurrency#Proc::Async> interaction with the
running processes. In general, it is a good practice to interact with the system
through these high-level, abstract interfaces. However, Raku provides with
other ways of interacting with the system through a low-level interface.

=head1 Making operating system calls through the native API

The L<C<NativeCall>|/language/nativecall> API can be used to interact with
system libraries, as well as any other accessible library. This
L<short tutorial|/language/nativecall#Short_tutorial_on_calling_a_C_function>
explains, for instance, how to call system functions such as C<getaddrinfo>
using that interface; some other functions like C<kill> can also be L<accessed
that way, via declaration using the NativeCall
interface|/language/5to6-perlfunc#kill>.

Fortunately, you do not have to do that for all native functions. As part of her
Butterfly project porting Perl functions to Raku as part of the ecosystem,
L<Elizabeth Mattijsen|https://github.com/lizmat> is porting many system
functions that were part of that language to modules such as
L<C<P5getprotobyname>|https://github.com/lizmat/P5getprotobyname>, which
includes functions such as C<endprotoent>, C<getprotoent>, C<getprotobyname>,
C<getprotobynumber> and C<setprotoent>.
L<Search and install C<P5> modules|https://modules.raku.org/search/?q=p5>
if you want to use those functions already in Raku.

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
